package com.xm.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class OrderService {
    //确保所有使用 @Autowired 的类均被 @Component、@Service 等注解标记，或通过构造函数显式传递依赖。
//    @Autowired
    /**
     * 官方推荐使用 构造函数注入 替代 字段注入，主要原因包括：
     *   1、不可变性：字段注入无法声明final，导致依赖可变
     *   2、可测试性：字段注入依赖Spring容器，单元测试时需通过反射手动注入依赖
     *   3、循环依赖风险：构造函数注入能在编译器暴露循环依赖问题
     *   4、代码可读性：构造函数明确展示类的依赖关系
     */
    private final StringRedisTemplate redisTemplateCas;

    public OrderService(StringRedisTemplate redisTemplateCas) {
        this.redisTemplateCas = redisTemplateCas;
    }

    public void createOrder(String orderId) {
        String lockKey = "order:lock:" + orderId;
        RedisDistributedLock lock = new RedisDistributedLock(redisTemplateCas, lockKey, 30000);

        try {
            // 尝试获取锁，设置重试机制
            if (!lock.tryLock()) {
                throw new RuntimeException("系统繁忙，请稍后再试！");
            }
            log.info("已获取锁。");
            Thread.sleep(10000);// 测试锁对象是否在 redis 中

            // 执行业务逻辑
            processOrder(orderId);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
            log.info("锁已释放。");
        }
    }

    public void processOrder(String orderId) throws InterruptedException {
        // 订单处理逻辑
        log.info("订单处理中..");

        Thread.sleep(2000);

        log.info("订单处理完成。");
    }

}
